import pytest
from common.request_util_test import RequestUtil
from common.test_yaml_util_test import YamlUtil
import os.path
from config import datas


class TestAppManagement:
    @pytest.mark.parametrize('yaml', YamlUtil().read_testcase_yaml('v24.09/appManagement/POST_helm_install.yaml'))
    def test_helm_install(self, yaml):
        # 安装Helm Release
        # 首先上传3个chart包到本地仓库（因为本地包比较稳定，且部署速度更快）
        method_upload_chart = "POST"
        url_upload_chart = datas.baseUrl + "/rest/marketplace/v1beta1/helm-charts"
        file_path1 = os.path.dirname(
            __file__) + '/../../../data/v24.09/repoManagement/test-chart-stress-runner-ext-v1.tgz'
        with open(file_path1, 'rb') as file1:
            req_upload_chart1 = RequestUtil().send_request(method_upload_chart, url_upload_chart,
                                                           files={'chart': file1})
            assert req_upload_chart1.status_code == 201
        file_path2 = os.path.dirname(
            __file__) + '/../../../data/v24.09/repoManagement/test-chart-stress-runner-ext-v2.tgz'
        with open(file_path2, 'rb') as file2:
            req_upload_chart2 = RequestUtil().send_request(method_upload_chart, url_upload_chart,
                                                           files={'chart': file2})
            assert req_upload_chart2.status_code == 201
        file_path3 = os.path.dirname(
            __file__) + '/../../../data/v24.09/repoManagement/test-chart-stress-runner-ext-v3.tgz'
        with open(file_path3, 'rb') as file3:
            req_upload_chart3 = RequestUtil().send_request(method_upload_chart, url_upload_chart,
                                                           files={'chart': file3})
            assert req_upload_chart3.status_code == 201
        # 用例健壮性增强：检测当前是否已安装了测试用的helm应用。如果已安装则先卸载
        uri_installed_ext = "/clusters/host/rest/application-management/v1beta1/helm-releases?extension=true"
        url_installed_ext = datas.baseUrl + uri_installed_ext
        method_installed_ext = "GET"
        headers_installed_ext = {"Content-Type": "application/json"}
        req_installed_ext = RequestUtil().send_request(method_installed_ext, url_installed_ext,
                                                       headers=headers_installed_ext)
        req_installed_ext = req_installed_ext.json()  # 将返回信息读取为json格式。如果是content()则会读取为bytes类型数据
        for i in req_installed_ext["data"]["items"]:
            if i["name"] == datas.test_app_management["release"]:
                # 如果找到test-chart-stress-runner-ext则卸载
                # print("test-chart-stress-runner-ext已安装，先卸载，再重新验证安装过程")
                uri_delete_app = "/rest/application-management/v1beta1/helm-releases/namespace/{namespace}/release/{release}"
                uri_delete_app = uri_delete_app.replace("{namespace}", i["namespace"])
                uri_delete_app = uri_delete_app.replace("{release}", datas.test_app_management["release"])
                url_delete_app = datas.baseUrl + uri_delete_app
                method_delete_app = "DELETE"
                headers_delete_app = {"Content-Type": "application/json"}
                req_delete_app = RequestUtil().send_request(method_delete_app, url_delete_app,
                                                            headers=headers_delete_app)
                assert req_delete_app.status_code == 200
                # print("test-chart-stress-runner-ext卸载成功")
                break
            else:
                continue
        # 安装测试用的helm应用 test-chart-stress-runner-ext
        uri = yaml['request']['url'].replace("{namespace}", datas.test_app_management["namespace"])
        uri = uri.replace("{release}", datas.test_app_management["release"])
        url = datas.baseUrl + uri
        # print(url)
        method = yaml['request']['method']
        headers = yaml['request']['headers']
        data = yaml['request']['data']
        req1 = RequestUtil().send_request(method, url, headers=headers, json=data)
        assert req1.status_code == yaml['validate'][0]['equals']['status_code']

    @pytest.mark.parametrize('yaml',
                             YamlUtil().read_testcase_yaml('v24.09/appManagement/GET_get_chart_installing_stat.yaml'))
    def test_get_chart_installing_stat(self, yaml):
        # 获取某个chart安装后的状态
        uri = yaml['request']['url'].replace("{release}", datas.test_app_management["release"])
        url = datas.baseUrl + uri
        method = yaml['request']['method']
        headers = yaml['request']['headers']
        data = yaml['request']['data']
        req = RequestUtil().send_request(method, url, headers=headers, json=data)
        assert req.status_code == yaml['validate'][0]['equals']['status_code']

    @pytest.mark.parametrize('yaml',
                             YamlUtil().read_testcase_yaml('v24.09/appManagement/GET_get_all_helm_release_info.yaml'))
    def test_get_all_helm_release_info(self, yaml):
        # 获取所有helm release的基本信息
        url = datas.baseUrl + yaml['request']['url']
        method = yaml['request']['method']
        headers = yaml['request']['headers']
        data = yaml['request']['data']
        req = RequestUtil().send_request(method, url, headers=headers, json=data)
        assert req.status_code == yaml['validate'][0]['equals']['status_code']

    @pytest.mark.parametrize('yaml', YamlUtil().read_testcase_yaml(
        'v24.09/appManagement/GET_get_specified_helm_release_info.yaml'))
    def test_get_specified_helm_release_info(self, yaml):
        # 获取指定helm release所有信息
        uri = yaml['request']['url'].replace("{namespace}", datas.test_app_management["namespace"])
        uri = uri.replace("{release}", datas.test_app_management["release"])
        url = datas.baseUrl + uri
        method = yaml['request']['method']
        headers = yaml['request']['headers']
        data = yaml['request']['data']
        req = RequestUtil().send_request(method, url, headers=headers, json=data)
        assert req.status_code == yaml['validate'][0]['equals']['status_code']

    #
    @pytest.mark.parametrize('yaml', YamlUtil().read_testcase_yaml('v24.09/appManagement/PUT_update_helm_release.yaml'))
    def test_update_helm_release(self, yaml):
        # 升级（升级时可以将目标版本设为相同，返回都是202升级成功）
        uri = yaml['request']['url'].replace("{namespace}", datas.test_app_management["namespace"])
        uri = uri.replace("{release}", datas.test_app_management["release"])
        url = datas.baseUrl + uri
        method = yaml['request']['method']
        headers = yaml['request']['headers']
        data = yaml['request']['data']
        req = RequestUtil().send_request(method, url, headers=headers, json=data)
        assert req.status_code == yaml['validate'][0]['equals']['status_code']

    @pytest.mark.parametrize('yaml', YamlUtil().read_testcase_yaml(
        'v24.09/appManagement/GET_get_specified_helm_release_history_version.yaml'))
    def test_get_specified_helm_release_history_version(self, yaml):
        # 获取release的全部历史版本
        uri = yaml['request']['url'].replace("{namespace}", datas.test_app_management["namespace"])
        uri = uri.replace("{release}", datas.test_app_management["release"])
        url = datas.baseUrl + uri
        method = yaml['request']['method']
        headers = yaml['request']['headers']
        data = yaml['request']['data']
        req = RequestUtil().send_request(method, url, headers=headers, json=data)
        assert req.status_code == yaml['validate'][0]['equals']['status_code']

    @pytest.mark.parametrize('yaml',
                             YamlUtil().read_testcase_yaml('v24.09/appManagement/POST_rollback_helm_release.yaml'))
    def test_rollback_helm_release(self, yaml):
        # 回退（回退时可以将目标版本设为相同，返回都是200回退成功）
        # 注意openFuyao最多存储11个历史版本。如果不断升级版本，增加到序号12，则较早的1号版本会被释放，导致回退失败
        uri = yaml['request']['url'].replace("{namespace}", datas.test_app_management["namespace"])
        uri = uri.replace("{release}", datas.test_app_management["release"])
        uri = uri.replace("{int}", datas.test_app_management["rollback_version"])
        url = datas.baseUrl + uri
        method = yaml['request']['method']
        headers = yaml['request']['headers']
        data = yaml['request']['data']
        req = RequestUtil().send_request(method, url, headers=headers, json=data)
        assert req.status_code == yaml['validate'][0]['equals']['status_code']

    @pytest.mark.parametrize('yaml', YamlUtil().read_testcase_yaml(
        'v24.09/appManagement/GET_get_specified_helm_release_manifest.yaml'))
    def test_get_specified_helm_release_manifest(self, yaml):
        # manifest获取（release的yaml获取）
        uri = yaml['request']['url'].replace("{namespace}", datas.test_app_management["namespace"])
        uri = uri.replace("{release}", datas.test_app_management["release"])
        url = datas.baseUrl + uri
        method = yaml['request']['method']
        headers = yaml['request']['headers']
        data = yaml['request']['data']
        req = RequestUtil().send_request(method, url, headers=headers, json=data)
        assert req.status_code == yaml['validate'][0]['equals']['status_code']

    @pytest.mark.parametrize('yaml', YamlUtil().read_testcase_yaml(
        'v24.09/appManagement/GET_get_specified_helm_release_values.yaml'))
    def test_get_specified_helm_release_values(self, yaml):
        # values获取
        uri = yaml['request']['url'].replace("{namespace}", datas.test_app_management["namespace"])
        uri = uri.replace("{release}", datas.test_app_management["release"])
        url = datas.baseUrl + uri
        method = yaml['request']['method']
        headers = yaml['request']['headers']
        data = yaml['request']['data']
        req = RequestUtil().send_request(method, url, headers=headers, json=data)
        assert req.status_code == yaml['validate'][0]['equals']['status_code']

    @pytest.mark.parametrize('yaml', YamlUtil().read_testcase_yaml(
        'v24.09/appManagement/GET_get_specified_helm_release_pod_container.yaml'))
    def test_get_specified_helm_release_pod_container(self, yaml):
        # 获取release内的所有pod和container，提供日志的请求参数
        uri = yaml['request']['url'].replace("{namespace}", datas.test_app_management["namespace"])
        uri = uri.replace("{release}", datas.test_app_management["release"])
        url = datas.baseUrl + uri
        method = yaml['request']['method']
        headers = yaml['request']['headers']
        data = yaml['request']['data']
        req = RequestUtil().send_request(method, url, headers=headers, json=data)
        assert req.status_code == yaml['validate'][0]['equals']['status_code']

    @pytest.mark.parametrize('yaml',
                             YamlUtil().read_testcase_yaml('v24.09/appManagement/DELETE_delete_helm_release.yaml'))
    def test_delete_helm_release(self, yaml):
        # 删除Helm Release
        uri = yaml['request']['url'].replace("{namespace}", datas.test_app_management["namespace"])
        uri = uri.replace("{release}", datas.test_app_management["release"])
        url = datas.baseUrl + uri
        method = yaml['request']['method']
        headers = yaml['request']['headers']
        data = yaml['request']['data']
        req = RequestUtil().send_request(method, url, headers=headers, json=data)
        assert req.status_code == yaml['validate'][0]['equals']['status_code']
        # 删除之前上传到本地仓的chart包（删除test-chart-stress-runner-ext的全部版本）
        method_delete_chart = "DELETE"
        url_delete_chart = datas.baseUrl + "/rest/marketplace/v1beta1/helm-charts/test-chart-stress-runner-ext"
        req_delete_chart = RequestUtil().send_request(method_delete_chart, url_delete_chart)
        assert req_delete_chart.status_code == 200
